From c575a85233cfea2e0935a5609e4e13d980a8c28f Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 20 Feb 2024 21:17:59 -0500 Subject: audio: rewrite IAudioDevice --- src/audio_core/renderer/audio_device.cpp | 14 +- src/audio_core/renderer/audio_device.h | 6 +- src/common/string_util.cpp | 4 + src/common/string_util.h | 1 + src/core/hle/service/audio/audio_device.cpp | 180 ++++++++++------------- src/core/hle/service/audio/audio_device.h | 41 ++++-- src/core/hle/service/audio/audio_in_manager.cpp | 3 +- src/core/hle/service/audio/audio_out_manager.cpp | 4 +- 8 files changed, 127 insertions(+), 126 deletions(-) diff --git a/src/audio_core/renderer/audio_device.cpp b/src/audio_core/renderer/audio_device.cpp index 2d9bf82bb..5be5594f6 100644 --- a/src/audio_core/renderer/audio_device.cpp +++ b/src/audio_core/renderer/audio_device.cpp @@ -36,8 +36,7 @@ AudioDevice::AudioDevice(Core::System& system, const u64 applet_resource_user_id : output_sink{system.AudioCore().GetOutputSink()}, applet_resource_user_id{applet_resource_user_id_}, user_revision{revision} {} -u32 AudioDevice::ListAudioDeviceName(std::vector& out_buffer, - const size_t max_count) const { +u32 AudioDevice::ListAudioDeviceName(std::span out_buffer) const { std::span names{}; if (CheckFeatureSupported(SupportTags::AudioUsbDeviceOutput, user_revision)) { @@ -46,19 +45,18 @@ u32 AudioDevice::ListAudioDeviceName(std::vector& out_buffer, names = device_names; } - const u32 out_count{static_cast(std::min(max_count, names.size()))}; + const u32 out_count{static_cast(std::min(out_buffer.size(), names.size()))}; for (u32 i = 0; i < out_count; i++) { - out_buffer.push_back(names[i]); + out_buffer[i] = names[i]; } return out_count; } -u32 AudioDevice::ListAudioOutputDeviceName(std::vector& out_buffer, - const size_t max_count) const { - const u32 out_count{static_cast(std::min(max_count, output_device_names.size()))}; +u32 AudioDevice::ListAudioOutputDeviceName(std::span out_buffer) const { + const u32 out_count{static_cast(std::min(out_buffer.size(), output_device_names.size()))}; for (u32 i = 0; i < out_count; i++) { - out_buffer.push_back(output_device_names[i]); + out_buffer[i] = output_device_names[i]; } return out_count; } diff --git a/src/audio_core/renderer/audio_device.h b/src/audio_core/renderer/audio_device.h index ca4040add..4242dad30 100644 --- a/src/audio_core/renderer/audio_device.h +++ b/src/audio_core/renderer/audio_device.h @@ -36,20 +36,18 @@ public: * Get a list of the available output devices. * * @param out_buffer - Output buffer to write the available device names. - * @param max_count - Maximum number of devices to write (count of out_buffer). * @return Number of device names written. */ - u32 ListAudioDeviceName(std::vector& out_buffer, size_t max_count) const; + u32 ListAudioDeviceName(std::span out_buffer) const; /** * Get a list of the available output devices. * Different to above somehow... * * @param out_buffer - Output buffer to write the available device names. - * @param max_count - Maximum number of devices to write (count of out_buffer). * @return Number of device names written. */ - u32 ListAudioOutputDeviceName(std::vector& out_buffer, size_t max_count) const; + u32 ListAudioOutputDeviceName(std::span out_buffer) const; /** * Set the volume of all streams in the backend sink. diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index 72c481798..1909aced5 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp @@ -38,6 +38,10 @@ std::string StringFromBuffer(std::span data) { return std::string(data.begin(), std::find(data.begin(), data.end(), '\0')); } +std::string StringFromBuffer(std::span data) { + return std::string(data.begin(), std::find(data.begin(), data.end(), '\0')); +} + // Turns " hej " into "hej". Also handles tabs. std::string StripSpaces(const std::string& str) { const std::size_t s = str.find_first_not_of(" \t\r\n"); diff --git a/src/common/string_util.h b/src/common/string_util.h index 9da1ca4e9..53d0549ca 100644 --- a/src/common/string_util.h +++ b/src/common/string_util.h @@ -19,6 +19,7 @@ namespace Common { [[nodiscard]] std::string ToUpper(std::string str); [[nodiscard]] std::string StringFromBuffer(std::span data); +[[nodiscard]] std::string StringFromBuffer(std::span data); [[nodiscard]] std::string StripSpaces(const std::string& s); [[nodiscard]] std::string StripQuotes(const std::string& s); diff --git a/src/core/hle/service/audio/audio_device.cpp b/src/core/hle/service/audio/audio_device.cpp index 3608d08c7..438f3cccd 100644 --- a/src/core/hle/service/audio/audio_device.cpp +++ b/src/core/hle/service/audio/audio_device.cpp @@ -4,7 +4,7 @@ #include "audio_core/audio_core.h" #include "common/string_util.h" #include "core/hle/service/audio/audio_device.h" -#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/cmif_serialization.h" namespace Service::Audio { using namespace AudioCore::Renderer; @@ -15,20 +15,20 @@ IAudioDevice::IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u impl{std::make_unique(system_, applet_resource_user_id, revision)}, event{service_context.CreateEvent(fmt::format("IAudioDeviceEvent-{}", device_num))} { static const FunctionInfo functions[] = { - {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"}, - {1, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolume"}, - {2, &IAudioDevice::GetAudioDeviceOutputVolume, "GetAudioDeviceOutputVolume"}, - {3, &IAudioDevice::GetActiveAudioDeviceName, "GetActiveAudioDeviceName"}, - {4, &IAudioDevice::QueryAudioDeviceSystemEvent, "QueryAudioDeviceSystemEvent"}, - {5, &IAudioDevice::GetActiveChannelCount, "GetActiveChannelCount"}, - {6, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceNameAuto"}, - {7, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolumeAuto"}, - {8, &IAudioDevice::GetAudioDeviceOutputVolume, "GetAudioDeviceOutputVolumeAuto"}, - {10, &IAudioDevice::GetActiveAudioDeviceName, "GetActiveAudioDeviceNameAuto"}, - {11, &IAudioDevice::QueryAudioDeviceInputEvent, "QueryAudioDeviceInputEvent"}, - {12, &IAudioDevice::QueryAudioDeviceOutputEvent, "QueryAudioDeviceOutputEvent"}, - {13, &IAudioDevice::GetActiveAudioDeviceName, "GetActiveAudioOutputDeviceName"}, - {14, &IAudioDevice::ListAudioOutputDeviceName, "ListAudioOutputDeviceName"}, + {0, D<&IAudioDevice::ListAudioDeviceName>, "ListAudioDeviceName"}, + {1, D<&IAudioDevice::SetAudioDeviceOutputVolume>, "SetAudioDeviceOutputVolume"}, + {2, D<&IAudioDevice::GetAudioDeviceOutputVolume>, "GetAudioDeviceOutputVolume"}, + {3, D<&IAudioDevice::GetActiveAudioDeviceName>, "GetActiveAudioDeviceName"}, + {4, D<&IAudioDevice::QueryAudioDeviceSystemEvent>, "QueryAudioDeviceSystemEvent"}, + {5, D<&IAudioDevice::GetActiveChannelCount>, "GetActiveChannelCount"}, + {6, D<&IAudioDevice::ListAudioDeviceNameAuto>, "ListAudioDeviceNameAuto"}, + {7, D<&IAudioDevice::SetAudioDeviceOutputVolumeAuto>, "SetAudioDeviceOutputVolumeAuto"}, + {8, D<&IAudioDevice::GetAudioDeviceOutputVolumeAuto>, "GetAudioDeviceOutputVolumeAuto"}, + {10, D<&IAudioDevice::GetActiveAudioDeviceNameAuto>, "GetActiveAudioDeviceNameAuto"}, + {11, D<&IAudioDevice::QueryAudioDeviceInputEvent>, "QueryAudioDeviceInputEvent"}, + {12, D<&IAudioDevice::QueryAudioDeviceOutputEvent>, "QueryAudioDeviceOutputEvent"}, + {13, D<&IAudioDevice::GetActiveAudioDeviceName>, "GetActiveAudioOutputDeviceName"}, + {14, D<&IAudioDevice::ListAudioOutputDeviceName>, "ListAudioOutputDeviceName"}, }; RegisterHandlers(functions); @@ -39,15 +39,33 @@ IAudioDevice::~IAudioDevice() { service_context.CloseEvent(event); } -void IAudioDevice::ListAudioDeviceName(HLERequestContext& ctx) { - const size_t in_count = ctx.GetWriteBufferNumElements(); +Result IAudioDevice::ListAudioDeviceName( + OutArray out_names, Out out_count) { + R_RETURN(this->ListAudioDeviceNameAuto(out_names, out_count)); +} + +Result IAudioDevice::SetAudioDeviceOutputVolume( + InArray name, f32 volume) { + R_RETURN(this->SetAudioDeviceOutputVolumeAuto(name, volume)); +} + +Result IAudioDevice::GetAudioDeviceOutputVolume( + Out out_volume, InArray name) { + R_RETURN(this->GetAudioDeviceOutputVolumeAuto(out_volume, name)); +} - std::vector out_names{}; +Result IAudioDevice::GetActiveAudioDeviceName( + OutArray out_name) { + R_RETURN(this->GetActiveAudioDeviceNameAuto(out_name)); +} - const u32 out_count = impl->ListAudioDeviceName(out_names, in_count); +Result IAudioDevice::ListAudioDeviceNameAuto( + OutArray out_names, + Out out_count) { + *out_count = impl->ListAudioDeviceName(out_names); std::string out{}; - for (u32 i = 0; i < out_count; i++) { + for (s32 i = 0; i < *out_count; i++) { std::string a{}; u32 j = 0; while (out_names[i].name[j] != '\0') { @@ -58,109 +76,77 @@ void IAudioDevice::ListAudioDeviceName(HLERequestContext& ctx) { } LOG_DEBUG(Service_Audio, "called.\nNames={}", out); - - IPC::ResponseBuilder rb{ctx, 3}; - - ctx.WriteBuffer(out_names); - - rb.Push(ResultSuccess); - rb.Push(out_count); + R_SUCCEED(); } -void IAudioDevice::SetAudioDeviceOutputVolume(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const f32 volume = rp.Pop(); - - const auto device_name_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(device_name_buffer); +Result IAudioDevice::SetAudioDeviceOutputVolumeAuto( + InArray name, f32 volume) { + R_UNLESS(!name.empty(), Audio::ResultInsufficientBuffer); - LOG_DEBUG(Service_Audio, "called. name={}, volume={}", name, volume); + const std::string device_name = Common::StringFromBuffer(name[0].name); + LOG_DEBUG(Service_Audio, "called. name={}, volume={}", device_name, volume); - if (name == "AudioTvOutput") { + if (device_name == "AudioTvOutput") { impl->SetDeviceVolumes(volume); } - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + R_SUCCEED(); } -void IAudioDevice::GetAudioDeviceOutputVolume(HLERequestContext& ctx) { - const auto device_name_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(device_name_buffer); +Result IAudioDevice::GetAudioDeviceOutputVolumeAuto( + Out out_volume, InArray name) { + R_UNLESS(!name.empty(), Audio::ResultInsufficientBuffer); - LOG_DEBUG(Service_Audio, "called. Name={}", name); + const std::string device_name = Common::StringFromBuffer(name[0].name); + LOG_DEBUG(Service_Audio, "called. Name={}", device_name); - f32 volume{1.0f}; - if (name == "AudioTvOutput") { - volume = impl->GetDeviceVolume(name); + *out_volume = 1.0f; + if (device_name == "AudioTvOutput") { + *out_volume = impl->GetDeviceVolume(device_name); } - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(volume); + R_SUCCEED(); } -void IAudioDevice::GetActiveAudioDeviceName(HLERequestContext& ctx) { - const auto write_size = ctx.GetWriteBufferSize(); - std::string out_name{"AudioTvOutput"}; - - LOG_DEBUG(Service_Audio, "(STUBBED) called. Name={}", out_name); - - out_name.resize(write_size); - - ctx.WriteBuffer(out_name); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); +Result IAudioDevice::GetActiveAudioDeviceNameAuto( + OutArray out_name) { + R_UNLESS(!out_name.empty(), Audio::ResultInsufficientBuffer); + out_name[0] = AudioDevice::AudioDeviceName("AudioTvOutput"); + LOG_DEBUG(Service_Audio, "(STUBBED) called"); + R_SUCCEED(); } -void IAudioDevice::QueryAudioDeviceSystemEvent(HLERequestContext& ctx) { +Result IAudioDevice::QueryAudioDeviceSystemEvent(OutCopyHandle out_event) { LOG_DEBUG(Service_Audio, "(STUBBED) called"); - event->Signal(); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(event->GetReadableEvent()); -} - -void IAudioDevice::GetActiveChannelCount(HLERequestContext& ctx) { - const auto& sink{system.AudioCore().GetOutputSink()}; - u32 channel_count{sink.GetSystemChannels()}; - - LOG_DEBUG(Service_Audio, "(STUBBED) called. Channels={}", channel_count); - - IPC::ResponseBuilder rb{ctx, 3}; - - rb.Push(ResultSuccess); - rb.Push(channel_count); + *out_event = &event->GetReadableEvent(); + R_SUCCEED(); } -void IAudioDevice::QueryAudioDeviceInputEvent(HLERequestContext& ctx) { +Result IAudioDevice::QueryAudioDeviceInputEvent(OutCopyHandle out_event) { LOG_DEBUG(Service_Audio, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(event->GetReadableEvent()); + *out_event = &event->GetReadableEvent(); + R_SUCCEED(); } -void IAudioDevice::QueryAudioDeviceOutputEvent(HLERequestContext& ctx) { +Result IAudioDevice::QueryAudioDeviceOutputEvent(OutCopyHandle out_event) { LOG_DEBUG(Service_Audio, "called"); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(event->GetReadableEvent()); + *out_event = &event->GetReadableEvent(); + R_SUCCEED(); } -void IAudioDevice::ListAudioOutputDeviceName(HLERequestContext& ctx) { - const size_t in_count = ctx.GetWriteBufferNumElements(); - - std::vector out_names{}; +Result IAudioDevice::GetActiveChannelCount(Out out_active_channel_count) { + *out_active_channel_count = system.AudioCore().GetOutputSink().GetSystemChannels(); + LOG_DEBUG(Service_Audio, "(STUBBED) called. Channels={}", *out_active_channel_count); + R_SUCCEED(); +} - const u32 out_count = impl->ListAudioOutputDeviceName(out_names, in_count); +Result IAudioDevice::ListAudioOutputDeviceName( + OutArray out_names, Out out_count) { + *out_count = impl->ListAudioOutputDeviceName(out_names); std::string out{}; - for (u32 i = 0; i < out_count; i++) { + for (s32 i = 0; i < *out_count; i++) { std::string a{}; u32 j = 0; while (out_names[i].name[j] != '\0') { @@ -171,13 +157,7 @@ void IAudioDevice::ListAudioOutputDeviceName(HLERequestContext& ctx) { } LOG_DEBUG(Service_Audio, "called.\nNames={}", out); - - IPC::ResponseBuilder rb{ctx, 3}; - - ctx.WriteBuffer(out_names); - - rb.Push(ResultSuccess); - rb.Push(out_count); + R_SUCCEED(); } } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio_device.h b/src/core/hle/service/audio/audio_device.h index 850c60051..752157272 100644 --- a/src/core/hle/service/audio/audio_device.h +++ b/src/core/hle/service/audio/audio_device.h @@ -4,11 +4,18 @@ #pragma once #include "audio_core/renderer/audio_device.h" +#include "core/hle/service/cmif_types.h" #include "core/hle/service/kernel_helpers.h" #include "core/hle/service/service.h" +namespace Kernel { +class KReadableEvent; +} + namespace Service::Audio { +using AudioCore::Renderer::AudioDevice; + class IAudioDevice final : public ServiceFramework { public: @@ -17,15 +24,31 @@ public: ~IAudioDevice() override; private: - void ListAudioDeviceName(HLERequestContext& ctx); - void SetAudioDeviceOutputVolume(HLERequestContext& ctx); - void GetAudioDeviceOutputVolume(HLERequestContext& ctx); - void GetActiveAudioDeviceName(HLERequestContext& ctx); - void QueryAudioDeviceSystemEvent(HLERequestContext& ctx); - void GetActiveChannelCount(HLERequestContext& ctx); - void QueryAudioDeviceInputEvent(HLERequestContext& ctx); - void QueryAudioDeviceOutputEvent(HLERequestContext& ctx); - void ListAudioOutputDeviceName(HLERequestContext& ctx); + Result ListAudioDeviceName( + OutArray out_names, + Out out_count); + Result SetAudioDeviceOutputVolume( + InArray name, f32 volume); + Result GetAudioDeviceOutputVolume( + Out out_volume, InArray name); + Result GetActiveAudioDeviceName( + OutArray out_name); + Result ListAudioDeviceNameAuto( + OutArray out_names, + Out out_count); + Result SetAudioDeviceOutputVolumeAuto( + InArray name, f32 volume); + Result GetAudioDeviceOutputVolumeAuto( + Out out_volume, InArray name); + Result GetActiveAudioDeviceNameAuto( + OutArray out_name); + Result QueryAudioDeviceSystemEvent(OutCopyHandle out_event); + Result QueryAudioDeviceInputEvent(OutCopyHandle out_event); + Result QueryAudioDeviceOutputEvent(OutCopyHandle out_event); + Result GetActiveChannelCount(Out out_active_channel_count); + Result ListAudioOutputDeviceName( + OutArray out_names, + Out out_count); KernelHelpers::ServiceContext service_context; std::unique_ptr impl; diff --git a/src/core/hle/service/audio/audio_in_manager.cpp b/src/core/hle/service/audio/audio_in_manager.cpp index 9b67af367..d55da17c8 100644 --- a/src/core/hle/service/audio/audio_in_manager.cpp +++ b/src/core/hle/service/audio/audio_in_manager.cpp @@ -96,8 +96,7 @@ Result IAudioInManager::OpenAudioInProtocolSpecified( LOG_DEBUG(Service_Audio, "Opening new AudioIn, session_id={}, free sessions={}", new_session_id, impl->num_free_sessions); - const auto name_buffer = std::span(reinterpret_cast(name[0].name.data()), 0x100); - const auto device_name = Common::StringFromBuffer(name_buffer); + const auto device_name = Common::StringFromBuffer(name[0].name); *out_audio_in = std::make_shared(system, *impl, new_session_id, device_name, parameter, process_handle.Get(), aruid.pid); impl->sessions[new_session_id] = (*out_audio_in)->GetImpl(); diff --git a/src/core/hle/service/audio/audio_out_manager.cpp b/src/core/hle/service/audio/audio_out_manager.cpp index 780e1dcda..153445097 100644 --- a/src/core/hle/service/audio/audio_out_manager.cpp +++ b/src/core/hle/service/audio/audio_out_manager.cpp @@ -75,9 +75,7 @@ Result IAudioOutManager::OpenAudioOutAuto( R_TRY(impl->LinkToManager()); R_TRY(impl->AcquireSessionId(new_session_id)); - const auto name_buffer = std::span(reinterpret_cast(name[0].name.data()), 0x100); - const auto device_name = Common::StringFromBuffer(name_buffer); - + const auto device_name = Common::StringFromBuffer(name[0].name); LOG_DEBUG(Service_Audio, "Opening new AudioOut, sessionid={}, free sessions={}", new_session_id, impl->num_free_sessions); -- cgit v1.2.3